package service;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import model.Game;
import model.gameImpl.GameV3;

public class Service {
	private static Service instance;
	private List<Game> games;
	private List<Class<? extends Game>> gameClasses;

	private Service() {
		gameClasses = new ArrayList<Class<? extends Game>>();
		
		//For now, implemented games need to be mentioned here
		gameClasses.add(GameV3.class);
		
		games = instantiateGames();
	}

	public static Service getInstance() {
		if (instance == null)
			instance = new Service();

		return instance;
	}

	private List<Game> instantiateGames() {
		List<Game> games = new ArrayList<Game>();

		//for (Class<Game> gameClazz : findImplementedGames()) {
		for (Class<? extends Game> gameClazz : gameClasses) {
			try {
				games.add(((Class<Game>) gameClazz).newInstance());
				games.get(games.size()-1).initialize();
			} catch (InstantiationException e) {
			} catch (IllegalAccessException e) {
			}
		}

		return games;
	}

	/*private List<Class<Game>> findImplementedGames() {
		List<Class<Game>> games = new ArrayList<Class<Game>>();
		List<String> names = null;
		try {
			names = getPackageClassNames("model/gameImpl");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		//for (String clazzName : getClassNamesFromPackage("model.gameImpl")) {
		for (String clazzName : names) {
			try {
				Class<?> clazz = Class.forName(clazzName);
				if (clazz.getSuperclass() == Game.class) {
					games.add(((Class<Game>) clazz));
				}
			} catch (ClassNotFoundException e) {
			}
		}

		return games;
	}

	public ArrayList<String> getClassNamesFromPackage(String packageName) {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		URL packageURL;
		ArrayList<String> names = new ArrayList<String>();
		;

		packageName = packageName.replace(".", "/");
		packageURL = classLoader.getResource("model/gameImpl/");
		
		File folder = new File(packageURL.getFile());
		File[] contents = folder.listFiles();
		String entryName;
		for (File actual : contents) {
			entryName = actual.getName();
			entryName = entryName.substring(0, entryName.lastIndexOf('.'));
			names.add(entryName);
		}
		// }
		return names;
	}
	
	public List<String> getPackageClassNames(String packageName) throws IOException {
		List<String> names = new ArrayList<String>();
		
		for (File file : getPackageContent(packageName))
			names.add(file.getName());
		
		return names;
	}
	
	public File[] getPackageContent(String packageName) throws IOException {
	    ArrayList<File> list = new ArrayList<File>();
	    Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
	                            .getResources(packageName);
	    while (urls.hasMoreElements()) {
	        URL url = urls.nextElement();
	        File dir = new File(url.getFile());
	        for (File f : dir.listFiles()) {
	            list.add(f);
	        }
	    }
	    return list.toArray(new File[]{});
	}*/
	
	public List<Game> getGames() {
		return games;
	}

	public void setGames(List<Game> games) {
		this.games = games;
	}
}
